/** @jsxImportSource @emotion/react */
import * as React from "react";
import { Text } from "./Text";
// import PropTypes from "prop-types";
//旧版本依赖Sheet提供了 import { RequestCloseContext } from "./Sheet";
import { useTheme } from "./Theme/Providers";
import { noOp } from "./misc/noop";
// import { useTouchable,  } from "./Hooks/touchable-hook";
import cx from "classnames";
import { safeBind } from "./Hooks/compose-bind";
import {forwardRef, MouseEventHandler} from "react";
import {OnPressFunction} from "./Hooks/pressable-hook";



const KeyCodes = {
    ArrowUp: 38,
    ArrowDown: 40,
    Home: 36,
    End: 35
};

interface MenuListContextType {
    focus: boolean;
    onKeyDown: (e: React.KeyboardEvent) => void;
}

const MenuListContext = React.createContext<MenuListContextType>({
    focus: false,
    onKeyDown: () => {}
});

type ChildrenType = React.ReactElement<MenuItemProps>;

export interface MenuListProps extends React.HTMLAttributes<HTMLDivElement> {
    /** A combination of MenuItem, MenuLabel, and MenuDivider children
     * children: ChildrenType | ChildrenType[];
     *  */
    children: React.ReactNode;
    /** Useful if you are providing your own MenuItem children */
    focusableChildren?: React.ComponentType<any>[];
}

export const MenuList = ({
                             children,
                             focusableChildren = [],
                             ...other
                         }:MenuListProps) => {
    const theme = useTheme();
    const disabled = new Map();
    const [focusIndex, setFocusIndex] = React.useState<number | null>(null);
    const kids = React.Children.toArray(children);

    const focusComponents = [MenuItem, ...focusableChildren];
    const focusableItems = kids.filter(
        kid =>
            React.isValidElement(kid) &&
            focusComponents.indexOf(kid.type as React.ComponentType) > -1
    );

    const lastIndex = focusableItems.length - 1;
    const firstIndex = 0;

    return (
        <div
            role="menu"
            onKeyDown={(e: React.KeyboardEvent) => {
                if (
                    e.keyCode === KeyCodes.ArrowDown ||
                    (e.keyCode === KeyCodes.ArrowUp && focusIndex === null)
                ) {
                    e.preventDefault();
                    setFocusIndex(0);
                }else if (e.keyCode === 13) {
                    //菜单列表 回车 有何意义
                    e.stopPropagation();
                    e.preventDefault();
                }
            }}
            css={{
                minWidth: "200px",
                display: "block",
                padding: `${theme.spaces.sm} 0`
            }}
            {...other}
        >
            {kids.map(kid => {
                if (!React.isValidElement(kid)) {
                    return null;
                }

                const i = focusableItems.indexOf(kid);

                if (i < 0) {
                    return kid;
                }

                disabled.set(i, (kid.props as any).disabled);

                function focusDown(current: number) {
                    const next = current + 1 > lastIndex ? firstIndex : current + 1;
                    if (disabled.get(next)) {
                        focusDown(next);
                    } else {
                        setFocusIndex(next);
                    }
                }

                function focusUp(current: number) {
                    const next = current - 1 < firstIndex ? lastIndex : current - 1;
                    if (disabled.get(next)) {
                        focusUp(next);
                    } else {
                        setFocusIndex(next);
                    }
                }

                const index = focusIndex || 0;

                return (
                    <MenuListContext.Provider
                        key={i}
                        value={{
                            // !第一个菜单项目 默认就是focus= true;
                            focus: i === focusIndex,
                            onKeyDown: (e: React.KeyboardEvent) => {
                                if (e.keyCode === KeyCodes.ArrowDown) {
                                    e.preventDefault();
                                    focusDown(index);
                                } else if (e.keyCode === KeyCodes.ArrowUp) {
                                    e.preventDefault();
                                    focusUp(index);
                                } else if (e.keyCode === KeyCodes.Home) {
                                    e.preventDefault();
                                    setFocusIndex(firstIndex);
                                } else if (e.keyCode === KeyCodes.End) {
                                    e.preventDefault();
                                    setFocusIndex(lastIndex);
                                }else if (e.keyCode === 13) {
                                    //菜单列表 回车 有何意义
                                    e.stopPropagation();
                                    e.preventDefault();
                                }
                            }
                        }}
                    >
                        {kid}
                    </MenuListContext.Provider>
                );
            })}
        </div>
    );
};

MenuList.propTypes = {
    //focusableChildren: PropTypes.arrayOf(PropTypes.element)
};

//弹出菜单不能noBind；
//MenuItem需要ref()切换，不能被RouterLink代替
//手机ResponsivePopover+MenuItem还会遭遇点击点点透掉的问题；
interface MenuItemProps extends React.HTMLAttributes<Element> {
    /** Called when the menu item is selected. Generally use this instead of onClick. */
    onPress?: OnPressFunction;
    onClick?: (e: React.MouseEvent<HTMLElement>) => void;
    /** Disable this menu item */
    disabled?: boolean;
    /** Pass in a string to use standard text styles. Otherwise, pass in any other node. */
    children: React.ReactNode;
    /** Provide a custom component. Eg., ReactRouter Link */
    component?: React.ElementType<any>;
    /** optional content to appear to the right of the menu text */
    contentAfter?: React.ReactNode;
    /** optional content to appear to the left of the menu text */
    contentBefore?: React.ReactNode;
    /**紧凑布局的*/
    tight?: boolean;
    [key: string]: any;
}

type MenuDividerProps = React.HTMLAttributes<HTMLDivElement>;

export function MenuDivider(props: MenuDividerProps) {
    const theme = useTheme();
    return (
        <div
            css={{
                height: 0,
                margin: `${theme.spaces.sm} 0`,
                overflow: "hidden",
                borderTop: "1px solid",
                borderColor: theme.colors.border.muted
            }}
            {...props}
        />
    );
}

interface MenuLabelProps extends React.HTMLAttributes<HTMLDivElement> {
    /** The name of the label */
    children?: React.ReactNode;
}

export const MenuLabel = (props: MenuLabelProps) => {
    const theme = useTheme();
    return (
        <Text
            variant="uppercase"
            css={{
                padding: `${theme.spaces.xs} ${theme.spaces.md}`
            }}
            {...props}
        />
    );
};

// MenuLabel.propTypes = {
//     children: PropTypes.node
// };

/**将来准备恢复成 MenuItem ？参数不兼容onClick onPress;
 * 非touch事件版,onClick()时间;  DdMenu适用的。
 * 因为从外部注入的方式修正padding 需要像这样的全部都要选择上，或者 但！important！的也太武断
 divStyle={{
        padding: 0,
        [theme.mediaQueries.sm]: {
            padding: 0,
        },
        [theme.mediaQueries.md]: {
            padding: 0,
        },
        [theme.mediaQueries.lg]: {
            padding: 0,
        },
        [theme.mediaQueries.xl]: {
            padding: 0,
        },
    }}
 考虑加一个参数：tight 表示是否紧凑的菜单按钮。
 * */
export const MenuItem =({
           contentBefore,
           contentAfter,
           className = "",
           component: Component = "div",
           onPress = noOp,
           role = "menuitem",
           children,
           disabled,
           // onClick,
           tight,
           ref,
           ...other
       }:MenuItemProps ) => {

    const theme = useTheme();
    const dark = theme.colors.mode === "dark";

    //const touchScr = useMedia(`(any-pointer: coarse)`);
    //手机和大屏幕的内容维持一致：菜单区域大小高度应该差不多。
    return (
        <Component
            className={cx("MenuItem", "Touchable", className )}
            css={[
                {
                    cursor: "pointer",
                    opacity: disabled ? 0.3 : 1,
                    display: "flex",
                    lineHeight: theme.lineHeights.menus,
                    textDecoration: "none",
                    transition: "background-color 0.1s ease",
                    WebkitTapHighlightColor: "transparent",
                    color: theme.colors.text.default,
                    alignItems: "center",
                    ":focus": {
                        outline: theme.outline
                    },
                    ":focus:not([data-focus-visible-added])": {
                        outline: "none"
                    },
                    ":hover": {
                        background:  theme.colors.background.tint1
                    },
                    padding: 0,
                    "@media print": {
                        transition: 'unset',
                    },
                },
                !tight && (
                    {
                        padding: `${theme.spaces.xs} ${theme.spaces.sm}` ,
                        [theme.mediaQueries.sm]: {
                            padding: `${theme.spaces.none} ${theme.spaces.none}`
                        },
                        [theme.mediaQueries.md]: {
                            padding: `${theme.spaces.xs} calc(${theme.spaces.xs} + 0.35rem)`,
                        },
                        [theme.mediaQueries.lg]: {
                            padding: `${theme.spaces.xs} ${theme.spaces.md}`
                        },
                        [theme.mediaQueries.xl]: {
                            padding: `${theme.spaces.sm} ${theme.spaces.lg}`
                        },
                    }
                ),
            ]}
            role={role}
            tabIndex={disabled ? -1 : 0}
            data-trigger-close={true}
            {...safeBind(
                {
                    ref: ref,
                    onClick: (e: React.MouseEvent) => {
                        // console.log("弹出3菜Menu2ImmT !点了");
                        !disabled && onPress(e);
                    },
                    // onPointerUp: (e: React.PointerEvent ) => {  基本点击触发
                    //  加上能使得DdMenu在位于Panable可随意拉拽的组件底下，能够触发"lostpointercapture"的useDrag(state)消息event.type
                    //     e.stopPropagation();  }
                },
                other
            )}
        >
            {contentBefore}
            {typeof children === "string" ? (
                <Text
                    wrap={true}
                    css={{
                        paddingLeft: contentBefore ? theme.spaces.sm : 0,
                        paddingRight: contentAfter ? theme.spaces.sm : 0,
                        flex: 1,
                        color: "inherit",
                        lineHeight: theme.lineHeights.menus,
                    }}
                >
                    {children}
                </Text>
            ) : (
                children
            )}
            {typeof contentAfter === "string" ? (
                <Text muted>{contentAfter}</Text>
            ) : (
                contentAfter
            )}
        </Component>
    );
};
